import { ISchema } from '@formily/antd';

export function isJSON(str: string): boolean {
  try {
    const obj = JSON.parse(str);
    if (typeof obj === 'object' && obj) {
      return true;
    }
    return false;
  } catch (e) {
    return false;
  }
}

export function parseJsonStr(str: string): string {
  try {
    const jsonObj = JSON.parse(str);
    const strObj = JSON.stringify(jsonObj, null, 2);
    return strObj;
  } catch (e) {
    console.error(`${str} not json`);
    return str;
  }
}

export function getSchemaDefaults(obj: any) {
  let result: any = {};
  if (obj.type === 'array') {
    result = getSchemaDefaultsArray(obj) || [];
  } else if (obj.type === 'object') {
    result = getSchemaObjectArray(obj) || {};
  } else {
    result = {};
  }
  return result;
}

export function getSchemaDefaultsArray(obj: any) {
  const items = obj.items || [];
  return items.map((v: any) => {
    if (v.type === 'array') {
      return getSchemaDefaultsArray(v);
    }
    return getSchemaObjectArray(v);
  });
}

export function getSchemaObjectArray(obj: any) {
  const properties: any = obj.properties || {};
  const propertiesKeys = Object.keys(properties);
  const result: any = {};
  propertiesKeys.forEach((v) => {
    const item = properties[v];
    if (item.type === 'array') {
      result[v] = getSchemaDefaultsArray(item);
    } else if (item.type === 'object') {
      result[v] = getSchemaObjectArray(item);
    } else if (item.type === 'datasource') {
      result[v] = item.default || {};
    } else {
      result[v] = item.default || '';
    }
  });
  return result;
}

export function transfmSchemaValue(obj: any): any {
  let result: any = {};
  if (Array.isArray(obj)) {
    result = [];
    for (let i = 0; i < obj.length; i++) {
      result.push(transfmSchemaValue(obj[i]));
    }
  } else {
    const keys = Object.keys(obj);
    for (let j = 0; j < keys.length; j++) {
      const keytmps = keys[j].split('-');
      const keyLast = keytmps[keytmps.length - 1];
      if (typeof obj[keys[j]] === 'object') {
        result[keyLast] = transfmSchemaValue(obj[keys[j]]);
      } else {
        result[keyLast] = obj[keys[j]];
      }
    }
  }
  return result;
}

/**
 *
 * @param obj JSON.parse 解析后的对象
 * @param isDisabled 是否可编辑
 */
export function transfmSchemaStr(obj: any, isDisabled?: boolean): ISchema | boolean {
  const root: ISchema = {
    type: 'object',
    properties: {},
    display: true,
  };
  //  判断使用哪一种方式(array,object)处理json
  const bootmap: any = {
    array: transfmSchemaArray,
    object: transfmSchemaObject,
  };

  if (Object.keys(bootmap).indexOf(obj.type) >= 0) {
    let properties = bootmap[obj.type](obj, isDisabled);
    if (obj.type === 'object') {
      properties = properties.properties;
    }
    //  把处理json后生成的对象挂到root.propeties
    if (properties) {
      root.properties = properties;

      return root;
    }
  }
  return false;
}

/**
 *
 * @param obj 处理数组类型下的单个对象
 * @param isDisabled 是否可编辑
 * @param path 路径
 */
export function transfmSchemaObjArr(obj: any, isDisabled?: boolean, path: string = ''): any | boolean {
  const bootmap: any = {
    array: transfmSchemaArray,
    object: transfmSchemaObject,
  };

  if (Object.keys(bootmap).indexOf(obj.type) >= 0) {
    const properties = bootmap[obj.type](obj, isDisabled, path);
    if (properties && properties.properties && properties.properties.layout_card) {
      return properties.properties.layout_card;
    }
  }
  return false;
}

/**
 *
 * @param obj 处理单个object下的对象(叶子节点)
 * @param title 标题
 * @param isDisabled  是否可编辑
 * @param path 路径
 */
export function transfmSchemaItem(obj: any, title?: string, isDisabled?: boolean, path: string = ''): ISchema | boolean {
  const bootmap: any = {
    string: transfmSchemaString,
    integer: transfmSchemaInteger,
    number: transfmSchemaNumber,
    boolean: transfmSchemaBoolean,
    datasource: transfmSchemaJson,
  };
  if (Object.keys(bootmap).indexOf(obj.type) >= 0) {
    const schema = bootmap[obj.type](obj, title, isDisabled);
    if (schema) {
      return schema;
    }
  }
  return false;
}

/**
 *
 * @param obj 待解析的对象(内容为数组类型)
 * @param isDisabled 是否可编辑
 * @param path 处理路径（用于存在重复名称时的区分）
 * @param isproperties
 */
export function transfmSchemaArray(obj: any, isDisabled?: boolean, path: string = '', isproperties?: boolean): any | boolean {
  const { title = '', items = [], display = true } = obj;
  const boot: ISchema = {
    type: 'object',
    properties: {
      layout_card: {
        type: 'object',
        'x-component': 'card',
        'x-component-props': {
          title,
        },
        properties: {},
        display,
      },
    },
  };
  //  按数组方式解析
  const result = items.map((it: any, index: number) => {
    return transfmSchemaObjArr(it, isDisabled, `${path}-${index}`);
  });
  if (result.indexOf(false) >= 0) {
    return false;
  }
  result.forEach((v: any, index: number) => {
    if (boot.properties?.layout_card?.properties) {
      boot.properties.layout_card.properties[`layout_card_${index}`] = v;
    }
  });
  return boot.properties;
}

/**
 *
 * @param obj 处理类型为object的对象
 * @param isDisabled 是否可编辑
 * @param path 路径
 */
export function transfmSchemaObject(obj: any, isDisabled?: boolean, path: string = ''): any | boolean {
  const { title = '', properties = {}, display = true } = obj;
  const boot: ISchema = {
    type: 'object',
    properties: {
      layout_card: {
        type: 'object',
        'x-component': 'card',
        'x-component-props': {
          title,
        },
        properties: {},
        display,
      },
    },
  };

  const propetieKeys = Object.keys(properties);
  //  记录路径与key的映射
  const keyMapPaths: any = {};
  const objschemas = propetieKeys.map((itKey: string) => {
    if (!properties[itKey]) {
      return false;
    }
    keyMapPaths[itKey] = `${path}-${itKey}`;
    const item = properties[itKey];
    let nRes: any = null;
    if (item.type === 'object' || item.type === 'array') {
      nRes = transfmSchemaObjArr(item, isDisabled, `${path}-${itKey}`);
      // return res;
    } else if (['string', 'datasource', 'integer', 'number', 'boolean'].indexOf(item.type) >= 0) {
      nRes = transfmSchemaItem(item, itKey, isDisabled || item.readonly || false);
    }
    return nRes;
  });
  if (objschemas.indexOf(false) >= 0) {
    return false;
  }
  const propertiesRes: any = {};
  propetieKeys.forEach((key: string, seq: number) => {
    if (objschemas[seq]) {
      // propertiesRes[key] = objschemas[seq];
      //  TODO：为了避免渲染的时候相同的name渲染成相同的内容使用path处理
      propertiesRes[keyMapPaths[key]] = objschemas[seq];
    }
  });
  if (boot.properties?.layout_card.properties) {
    boot.properties.layout_card.properties = propertiesRes;
  }
  return boot;
}

export function transfmSchemaJson(obj: any, title?: string, isDisabled?: boolean): any | boolean {
  return {
    title,
    ...obj,
    'x-component-props': {
      disabled: isDisabled,
      type: obj['x-component-props'].type || '',
    },
  };
}

export function transfmSchemaString(obj: any, title?: string, isDisabled?: boolean): any | boolean {
  return {
    title,
    ...obj,
    // disable: isDisabled,
    'x-component-props': {
      disabled: isDisabled,
    },
    // 'x-props': { labelCol: { span: 8 }, wrapperCol: { span: 16 } },
  };
}

export function transfmSchemaInteger(obj: any, title?: string, isDisabled?: boolean): any | boolean {
  return {
    title,
    ...obj,
    'x-component-props': {
      disabled: isDisabled,
    },
    // 'x-props': { labelCol: { span: 8 }, wrapperCol: { span: 16 } },
    type: 'number',
  };
}

export function transfmSchemaNumber(obj: any, title?: string, isDisabled?: boolean): any | boolean {
  return {
    title,
    ...obj,
    'x-component-props': {
      disabled: isDisabled,
    },
    // 'x-props': { labelCol: { span: 8 }, wrapperCol: { span: 16 } },
  };
}

export function transfmSchemaBoolean(obj: any, title?: string, isDisabled?: boolean): any | boolean {
  return {
    title,
    ...obj,
    'x-component-props': {
      disabled: isDisabled,
    },
    // 'x-props': { labelCol: { span: 8 }, wrapperCol: { span: 16 } },
  };
}

export function randomColor(i: number) {
  const colors: string[] = ['#5B8FF9', '#56CE9F', '#596B8C', '#EEB81B', '#2A9243', '#3565D5', '#7127F3', '#CE9219', '#4D9ACE', '#00AC06', '#5D739B'];
  const length = colors.length || 5;
  return colors[i % length];
}

export function getArrDifference(oldArr: any[], newArr: any[]) {
  const diffArr = oldArr.concat(newArr).filter((v, i, arr) => {
    return arr.indexOf(v) === arr.lastIndexOf(v);
  });
  return diffArr;
}

export function megrePropertiesVal(schema: any, value: any, isDisabled: boolean = false) {
  if (schema.properties) {
    const keys = Object.keys(value);
    keys.forEach((v) => {
      if (schema.properties[v]) {
        // 如果有config
        if (v === 'config') {
          const configKeys = Object.keys(value[v]);
          console.log(configKeys);
          configKeys.forEach((configV) => {
            if (schema.properties[v].properties[configV]) {
              schema.properties[v].properties[configV].default = value[v][configV];
              schema.properties[v].properties[configV]['x-component-props'] = {
                ...schema.properties[v].properties[configV]['x-component-props'],
                disabled: isDisabled,
              };
            }
          });
        } else {
          schema.properties[v].default = value[v];
          schema.properties[v]['x-component-props'] = { ...schema.properties[v]['x-component-props'], disabled: isDisabled };
        }
      }
    });
  } else {
    // eslint-disable-next-line
    (schema.items || []).map((_schema: any, idx: number) => {
      if (schema.items.length !== value.length) {
        console.warn('schema的条数和值的条数不一致');
        return;
      }
      const keys = Object.keys(value[idx]);
      // 如果有config
      keys.forEach((v) => {
        if (_schema.properties[v]) {
          // 如果有config
          if (v === 'config') {
            const configKeys = Object.keys(value[idx][v]);
            console.log(configKeys);
            configKeys.forEach((configV) => {
              if (_schema.properties[v].properties[configV]) {
                _schema.properties[v].properties[configV].default = value[idx][v][configV];
                _schema.properties[v].properties[configV]['x-component-props'] = {
                  ..._schema.properties[v].properties[configV]['x-component-props'],
                  disabled: isDisabled,
                };
              }
            });
          } else {
            _schema.properties[v].default = value[idx][v];
            _schema.properties[v]['x-component-props'] = { ..._schema.properties[v]['x-component-props'], disabled: isDisabled };
          }
        }
      });
    });
  }
  return schema;
}

export function GetUnitMemory(memory: number) {
  const UnitMap: { unit: string; baseUn: number }[] = [
    {
      unit: 'B',
      baseUn: 1024,
    },
    {
      unit: 'KB',
      baseUn: 1024,
    },
    {
      unit: 'MB',
      baseUn: 1024,
    },
    {
      unit: 'GB',
      baseUn: 1024,
    },
    {
      unit: 'TB',
      baseUn: 1024,
    },
    {
      unit: 'PB',
      baseUn: 1024,
    },
  ];
  const result: { num: number; Unit: string } = { num: memory, Unit: 'B' };
  for (let i = 0; i < UnitMap.length; i++) {
    if (result.num < UnitMap[i].baseUn) {
      break;
    }
    if (result.Unit !== UnitMap[i].unit) {
      result.num = result.num / UnitMap[i].baseUn;
      result.Unit = UnitMap[i].unit;
    }
  }
  return `${Math.round(result.num)} ${result.Unit}`;
}

export function getFileName(file: string) {
  return file.substring(0, file.lastIndexOf('.'));
}

export function timediff(begin: string, end: string) {
  const _beginTime = transdate(begin);
  const _endTime = transdate(end);

  // 计算天数
  const _timediff = _endTime - _beginTime;
  const days = _timediff / 86400;
  // 计算小时数
  let remain = _timediff % 86400;
  const hours = remain / 3600;
  // 计算分钟数
  remain = remain % 3600;
  // const mins = remain / 60;
  // // 计算秒数
  // const secs = remain % 60;
  if (days || hours) {
    return `${parseInt(days.toString(), 10)}天${parseInt(hours.toString(), 10)}小时`;
  }
  return '暂无';
}

export function transdate(time: any) {
  const date: any = new Date();
  date.setFullYear(time.substring(0, 4));
  date.setMonth(time.substring(5, 7) - 1);
  date.setDate(time.substring(8, 10));
  date.setHours(time.substring(11, 13));
  date.setMinutes(time.substring(14, 16));
  date.setSeconds(time.substring(17, 19));

  return Date.parse(date) / 1000;
}

export function GetPercent(num: number, total: number) {
  num = parseFloat(num.toString());
  total = parseFloat(total.toString());
  if (isNaN(num) || isNaN(total)) {
    return '-';
  }
  return total <= 0 ? '0' : `${Math.round((num / total) * 10000) / 100.0}`;
}

export function ExportExcel(data: any[], title2: any[], downloadFileName: string, notDownloadColumns: any[] = []) {
  const result = [];
  const subTitle: any = [];
  const title: any = [];
  title2.map((val: any) => {
    if (notDownloadColumns.indexOf(val.name) === -1) {
      subTitle.push(val.title);
      title.push(val);
    } else if (val.children) {
      // eslint-disable-next-line
      val.children.map((c: any) => {
        if (notDownloadColumns.indexOf(c.name) === -1) {
          subTitle.push(`${val.title}_${c.title}`);
          title.push(c);
        }
      });
    }
    return false;
  });

  console.log('title');
  console.log(title);
  console.log(data);

  // eslint-disable-next-line
  data.map((value: any) => {
    const content: any = [];
    title.map((val: any) => {
      if (notDownloadColumns.indexOf(val.name) === -1) {
        const _value = value[val.title] || '';

        content.push(`"${_value.replace(/"/g, '""')}"t`);
      }
      return false;
    });
    result.push(content);
    // return;
  });
  result.unshift(subTitle);

  console.log('result');
  console.log(result);
  let csvContent = '';

  const _navigator = window.navigator;
  if ('msSaveOrOpenBlob' in _navigator) {
    csvContent = '\ufeff';
  }
  result.forEach((infoArray, index) => {
    const dataString = infoArray.join(',');
    csvContent += index < data.length ? `${dataString}\n` : dataString;
  });

  if ('msSaveOrOpenBlob' in _navigator) {
    // if browser is IE
    const blob = new Blob([decodeURIComponent(encodeURI(csvContent))], {
      type: 'text/csv;charset=utf-8;',
    });
    window.navigator.msSaveBlob(blob, `${downloadFileName}.csv`);
  } else {
    let csvUrl = '';
    if (typeof Blob !== 'undefined') {
      csvContent = `\uFEFF${csvContent}`;
      const csvData = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
      csvUrl = URL.createObjectURL(csvData);
    } else {
      csvContent = `data:text/csv;charset=utf-8,\ufeff${csvContent}`;
      csvUrl = encodeURI(csvContent);
    }
    const link = document.createElement('a');
    link.setAttribute('href', csvUrl);
    link.setAttribute('download', `${downloadFileName}.csv`);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }
}

// 获取文件后缀
export function getType(file: string) {
  const filename = file;
  const index1 = filename.lastIndexOf('.');
  const index2 = filename.length;
  const type = filename.substring(index1, index2);
  return type;
}

export function fakeClick(obj: any) {
  const ev = document.createEvent('MouseEvents');
  ev.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  obj.dispatchEvent(ev);
}

export function exportText(name: string, data: string) {
  const urlObject = window.URL || window.webkitURL || window;
  // eslint-disable-next-line
  const export_blob = new Blob([data]);
  // eslint-disable-next-line
  const save_link: any = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
  save_link.href = urlObject.createObjectURL(export_blob);
  save_link.download = name;
  fakeClick(save_link);
}

export function isJson(data: string) {
  try {
    if (typeof JSON.parse(data) == 'object') {
      return true;
    }
    // eslint-disable-next-line no-empty
  } catch (e) {}
  return false;
}

/**
 * 取出小括号内的内容
 * @param text
 * @returns {string}
 */
export function getParenthesesStr(text: string) {
  const result = text.match(/\(([^)]*)\)/);
  if (result) {
    return result[1];
  }
  return '';
}
